/*
 * ===================================================================
 *  
 *      Filename:  log_client_queue.c
 *
 *   Description:  This file is used to work as an queue  :)
 *
 *       Version:  1.0
 *        Create:  2010/07/13
 *
 *        Author:  Keven Zhu     kevenzhu@tencent.com
 *     Copyright:  Reserved by Tencent.com Co.ltd
 *          
 * ====================================================================
 */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>

#include "lib/util.h"
#include "log_client_queue.h"
#include "log_client_api.h"

/* Return the used share buffer to the queue
 * @ctl_header: ctl header for the share memory, containing the header and tailer index
 * @data:address for the used memory which will be released to the queue
 *
 * Return value:
 * positive means failure,the reason could be found in the header file or with plogerr()
 * 0 means OK*/
int enqueue(local_share_mem_ctl_header *local_ctl_header,char* data)
{
    int result    = NOERR;
    int fill_buff = 0;
   
    fill_buff = *(local_ctl_header->enqueue_counter) - *(local_ctl_header->dequeue_counter); 
    if(fill_buff < *(local_ctl_header->max_queue))
    {
        memcpy(local_ctl_header->log_list[(*(local_ctl_header->enqueue_counter))&(*(local_ctl_header->max_queue_mask))],data,*((short*)data));
        (*(local_ctl_header->enqueue_counter))++;
    }
    else
    {
        result = FQFUL;
    }
    return result;
}

/* Dequeue the packet from the queue, if the queue is empty, a NULL point will be returned;
 * @ctl_header:ctl header for the share memory
 * 
 * Return value:
 * positive means OK
 * NULL means the queue is empty
 * */
void* dequeue(local_share_mem_ctl_header *local_ctl_header)
{
    void* result = NULL;

    if(*(local_ctl_header->enqueue_counter) != *(local_ctl_header->dequeue_counter))
    {
        result = local_ctl_header->log_list[(*(local_ctl_header->dequeue_counter))&(*local_ctl_header->max_queue_mask)];
        (*(local_ctl_header->dequeue_counter))++;
    }
    else
    {
        /*pending the thread*/
        result = NULL;
    }
    
    return result;
}

/*initialize the queue for the share memory*/
void init_queue(share_mem_ctl_header *ctl_header, int max_queue)
{
    ctl_header->max_queue       = max_queue;
    ctl_header->max_queue_mask  = max_queue-1;
    ctl_header->enqueue_counter = 0;
    ctl_header->dequeue_counter = 0;
}

/*destroy the queue,nothing to do*/
void finit_queue(share_mem_ctl_header *ctl_header)
{

}

